package Computer;

import java.util.ArrayDeque;
import java.util.List;
import java.util.Queue;

import Process.Process;
import Process.Process.SysCall;

/**
 * CPU class.
 * 
 * @author Stephen Amos, Zach Turk, Dickson Kwong
 *
 */

public class CPU {

	private PCB running;
	private PCB interrupted;
	private Queue<PCB> ready;
	
	/**
	 * Creates a new CPU
	 * @param pcbs The pcbs to set up
	 */
	public CPU(List<PCB> pcbs) {
		ready = new ArrayDeque<PCB>();
		for (PCB pcb : pcbs) {
			ready.add(pcb);
		}
		if (ready.size() > 0) running = ready.poll();
	}
	
	/**
	 * Advance the CPU one step.
	 */

	public SysCall step(Process p) {
		return p.next();
	}
	
	/**
	 * @return Is the CPU done executing all processes?
	 */
	public boolean isFinished() {
		return running == null && interrupted == null && ready.size() == 0;
	}
	
	/**
	 * @return The running process' PCB
	 */
	public PCB running() {
		return running;
	}
	
	/**
	 * @param p The new running process' PCB
	 */
	public void setRunning(PCB p) {
		running = p;
	}
	
	/**
	 * @return The interrupted process' PCB
	 */
	public PCB interrupted() {
		return interrupted;
	}
	
	/**
	 * @param The newly interrupted process' PCB
	 */
	public void setInterrupted(PCB p) {
		interrupted = p;
	}
	
	/**
	 * @return List of processes' PCB that are waiting on the CPU
	 */
	public Queue<PCB> ready() {
		return ready;
	}
	
	/**
	 * @param p The new processes' PCB to add to the ready list.
	 */
	public void addPCB(PCB p) {
		ready.add(p);
	}
	
}